//
//  CZStatusDAL.m
//  XinLang_OC
//
//  Created by WONG on 16/4/3.
//  Copyright © 2016年 cheuhui. All rights reserved.
//

#import "CZStatusDAL.h"
#import "CZSQLiteManager.h"
#import "FMDB.h"


/*
    加载微博数据思路：
        1、进入首页，首先加载本地数据库的微博数据
        2、如果数据库没有微博数据，再去网络加载微博数据
        3、从网络加载好的微博数据保存至数据库
 */

@interface CZStatusDAL ()

/**
 *  有效期7天
 *  7 * 24 * 60 * 60秒
 */
@property(nonatomic,assign)NSTimeInterval overTime;

@end

@implementation CZStatusDAL

+ (instancetype)sharedInstance {
    static id instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (void)clearCachedStatus {
    // 计算过期时间
    NSDate *date = [[NSDate alloc] initWithTimeIntervalSinceNow:-self.overTime];
    NSLog(@"过期时间：date = %@",date);
    
    // 时间格式化
    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    df.locale = [NSLocale localeWithLocaleIdentifier:@"en"];
    df.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    NSString *overTimeString = [df stringFromDate:date];
    
    // sql语句
    NSString *sql = [NSString stringWithFormat:@"DELETE FROM T_Status WHERE createAt < '%@'",overTimeString];
    NSLog(@"delete sql = %@",sql);
    
    [[CZSQLiteManager sharedManager].dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        if ([db executeUpdate:sql]) {
            NSLog(@"删除数据库数据成功");
        } else {
            NSLog(@"删除数据库数据失败");
            
        }
    }];
}

/**
 *  加载微博数据
 *  1. 查找本地数据库
 *  2. 如果有数据直接返回
 *  3. 如果没有数据,发送网络请求加载网络上的数据
 *  4. 保存网络数据到数据库 (先保证数据库有数据)
 *  5. 将网络数据返回给调用者
 */
- (void)loadStatus:(NSNumber *)since_id max_id:(NSNumber *)max_id finished:(void (^)(NSArray *, NSError *))finished {
    // 1. 查找本地数据库
    [self loadCacheStatus:since_id max_id:max_id finished:^(NSArray *statuses) {
        if (statuses != nil && statuses.count > 0) {
            NSLog(@"加载本地的微博数据");
            // 2. 如果有数据直接返回
            finished(statuses, nil);
            return;
        }
        // 能到这里来说明本地数据库没有数据
        // 3. 如果没有数据,发送网络请求加载网络上的数据
        [[CZNetworkTool sharedHttpTool] loadStatus:since_id max_id:max_id finished:^(id result, NSError *error) {
            // 判断是否加载成功
            if (error != nil || result == nil) {
                NSLog(@"网络加载微博数据失败");
                finished(nil, error);
                return;
            }
            
            // 加载微博数据成功
            NSArray *array = result[@"statuses"];
            if (array != nil) {
                // 解析到微博数据
                // 4. 保存网络数据到数据库
                [self saveStatus:array];
                // 将网络数据返回给调用者
                finished(array, nil);
            } else {
                finished(nil, nil);
            }
        }];

    }];
}



/**
 *  到数据库加载微博数据
 */
- (void)loadCacheStatus:(NSNumber *)since_id max_id:(NSNumber *)max_id finished:(void (^)(NSArray *statuses))finished {
    // 获取用户的id
    NSString *uid = [CZUserAccount loadUserAccount].uid;
    // 断言
    NSAssert(uid != nil, @"账户没有uid");
    // sql
    NSString *sql = [NSString stringWithFormat:@"SELECT * FROM T_Status \n WHERE userId = %@ \n",uid];
    
    // since_id 下拉刷新, 不能少这个, 如果少了，就会从数据库加载20数据statusId没有限制,只有数据加载不到数据,才去网络上加载
    if (since_id > 0) {
        sql = [NSString stringWithFormat:@"%@ AND statusId > %@ \n",sql,since_id];
    }else if(max_id > 0) {
        sql = [NSString stringWithFormat:@"%@ AND statusId < %@ \n",sql,max_id];;
    }
    
    sql = [sql stringByAppendingString:@"ORDER BY statusId DESC LIMIT 20;"];
    NSLog(@"查询aql = %@",sql);
    
    // 执行查询sql获取数据库中的数据
    [[CZSQLiteManager sharedManager].dbQueue inDatabase:^(FMDatabase *db) {
        FMResultSet *result = [db executeQuery:sql];
        
        if (!result) {
            NSLog(@"没有查询到数据");
            finished(nil);
            return;
        }
        
        // 查询到数据，将查询到的数据转成数组字典返回
        NSMutableArray *statuses = [NSMutableArray array];
        
        while ([result next]) {
            NSString *statusStr = [result stringForColumn:@"status"];
            // NSString -> NSData -> JSON
            NSData *data = [statusStr dataUsingEncoding:NSUTF8StringEncoding];
            // 微博字典
            NSDictionary *status = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
            
            [statuses addObject:status];
        }
        finished(statuses);
    }];
}
/**
 *  保存微博数据
 *  status：微博数据的数组，一条微博数据对应一个字典
 */
- (void)saveStatus:(NSArray *)statuses {
    // 获取用户id
    NSString *uid = [CZUserAccount loadUserAccount].uid;
    NSAssert(uid != nil, @"账户没有uid");
    
    // OR REPLACE 替换数据
    // 替换主键相同的数据,必须要有主键
    // 主键不能是自动增长的
    NSString *sql = @"INSERT OR REPLACE INTO T_Status (statusId, status, userId) VALUES (?, ?, ?)";
    
    // 向数据库添加数据
    [[CZSQLiteManager sharedManager].dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        // 遍历每一条微博数据
        for (NSDictionary *status in statuses) {
            // 获取微博的id
            NSNumber *statusId = status[@"id"];
            
            // 数据库中不能直接存放字典,可以存放字符串
            // 字典(json) -> NSData -> String
            NSData *data = [NSJSONSerialization dataWithJSONObject:status options:0 error:NULL];
            // 微博内容字符串
            NSString *statusString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            
            // 保存到数据库
            if ([db executeUpdate:sql, statusId, statusString, uid]) {
                NSLog(@"添加微博数据到数据库 成功 statusId = %@",statusId);
            }else {
                NSLog(@"添加微博数据到数据库 失败 statusId = %@",statusId);
            }
        }
    }];
}




#pragma mark - lazy load

- (NSTimeInterval)overTime {
    if (!_overTime) {
        _overTime = 7 * 24 * 60 * 60; // 7天
    }
    return _overTime;
}

@end






















